home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMIBEST1.ADF / AmigaBasicStuff / FutureSound / playsound.c < prev    next >
C/C++ Source or Header  |  1987-07-22  |  4KB  |  227 lines

  1. /* PlaySound.c */
  2. /* This routine sets up an ioRequest and plays back a */
  3. /* waveform through the Amiga audio hardware */
  4.  
  5. /* Usage : PlaySound(buffer,repeat,period,volume) */
  6. /* buffer is a pointer to a waveform */
  7. /* repeat is the number of times to play the wave (0 == forever) */
  8. /* period determines the playback rate (minimum value == 124) */
  9. /* volume goes from 0 to 64 */
  10.  
  11. #include "exec/types.h"
  12. #include "devices/audio.h"
  13. #include "exec/memory.h"
  14. #include "SoundErrors.h"
  15.  
  16. #define LEFT0F            1
  17. #define RIGHT0F        2
  18. #define RIGHT1F        4
  19. #define LEFT1F            8
  20.  
  21. extern struct MsgPort *CreatePort();
  22.  
  23. /* Look for a left channel, then a right */
  24. UBYTE allocationMap[] = {LEFT0F,LEFT1F,RIGHT0F,RIGHT1F};
  25.  
  26. /* Allocate and initialize an IO Request Block */
  27. SetIOA(per,vol,repeat,len,ioa)
  28. int per,vol,repeat;
  29. ULONG len;
  30. struct IOAudio **ioa;
  31. {
  32.     struct MsgPort *port;
  33.     char *PortName;
  34.  
  35.     PortName = "Sound Channel";
  36.  
  37.     /* Allocate IOAudio structure */
  38.     (*ioa) = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),
  39.                                         MEMF_PUBLIC|MEMF_CLEAR);
  40.  
  41.     /* If Allocation Successful ... */
  42.     if((*ioa)!=0)
  43.     {
  44.         /* Set Priority */
  45.         (*ioa)->ioa_Request.io_Message.mn_Node.ln_Pri = 10;
  46.         /* Create Message port for IORequest to talk to Amiga */
  47.         if ((port = CreatePort(PortName,0)) == 0)
  48.         {
  49.             FreeMem((*ioa),sizeof(struct IOAudio));
  50.         }
  51.         /* If Creation Successful ... */
  52.         else
  53.         {
  54.             /* Get a channel */
  55.             (*ioa)->ioa_Request.io_Message.mn_ReplyPort = port;
  56.             (*ioa)->ioa_Data = allocationMap;
  57.             (*ioa)->ioa_Length = sizeof(allocationMap);
  58.             /* Open Audio Device for output */
  59.             if(OpenDevice(AUDIONAME,0,(*ioa),0) != 0)
  60.             {
  61.                 DeletePort(port);
  62.                 FreeMem((*ioa),sizeof(struct IOAudio));
  63.             }
  64.             /* If open worked ... */
  65.             else
  66.             {
  67.                 /* Set Up Request */
  68.                 (*ioa)->ioa_Request.io_Flags = ADIOF_PERVOL;
  69.                 (*ioa)->ioa_Request.io_Command = CMD_WRITE;
  70.                 (*ioa)->ioa_Period = per;
  71.                 (*ioa)->ioa_Volume = vol;
  72.  
  73.                 /* For some reason, the Audio chip can't play samples */
  74.                 /* longer than 131k, so we kludge.  Oh, well. */
  75.                 if(len<131000)
  76.                 {
  77.                     (*ioa)->ioa_Cycles = repeat;
  78.                 }
  79.                 else
  80.                 {
  81.                     (*ioa)->ioa_Cycles = 1;
  82.                 }
  83.             }
  84.         }
  85.     }
  86. }
  87.  
  88. /* Play a sound */
  89. struct IOAudio *PlaySound(buffer,buflen,repeat,period,volume)
  90. BYTE *buffer;
  91. ULONG buflen;
  92. int repeat,period,volume;
  93. {
  94.     struct IOAudio *ioa;
  95.     BYTE *DataPtr;
  96.     ULONG PlayLen=0;
  97.     int sound_done=0;
  98.     int count;
  99.  
  100.     count = repeat?(repeat-1):-1;
  101.     DataPtr = buffer;
  102.  
  103.     /* Set Up IOAudio structure */
  104.     SetIOA(period,volume,repeat,buflen,&ioa);
  105.  
  106.     /* Set up data and length pointers of ioa */
  107.     SetLength(&PlayLen,buflen,&DataPtr,ioa);
  108.  
  109.     /* Send command to Audio chip */
  110.     BeginIO(ioa);
  111.  
  112.     /* If no data remains to play, return ioa pointer */
  113.     if(PlayLen == 0)
  114.     {
  115.         return(ioa);
  116.     }
  117.  
  118.     /* If there is more (buflen >131000), continue until there isn't */
  119.     while(!sound_done)
  120.     {
  121.         /* If current chunk is done ... */
  122.         if(CheckIO(ioa))
  123.         {
  124.             /* If more remains, continue */
  125.             if(PlayLen > 0)
  126.             {
  127.                 /* update pointers and start next chunk */
  128.                 FixLength(&PlayLen,&DataPtr,ioa);
  129.                 BeginIO(ioa);
  130.                 if((PlayLen == 0) && (count == 0))
  131.                 {
  132.                     return(ioa);
  133.                 }
  134.             }
  135.             /* If not ... */
  136.             else
  137.             {
  138.                 /* Check repeat counter */
  139.                 if(count != 0)
  140.                 {
  141.                     /* Restart wave */
  142.                     DataPtr = buffer;
  143.                     SetLength(&PlayLen,buflen,&DataPtr,ioa);
  144.                     BeginIO(ioa);
  145.                     if(count>0)
  146.                     {
  147.                         count--;
  148.                     }
  149.                 }
  150.                 else
  151.                 {
  152.                     /* finished */
  153.                     sound_done = 1;
  154.                 }
  155.             }
  156.         }
  157.     }
  158.     /* Free IOAudio stuff */
  159.     StopSound(ioa);
  160. }
  161.  
  162. StopSound(ioa)
  163. struct IOAudio *ioa;
  164. {
  165.     AbortIO(ioa);
  166.     if(ioa->ioa_Request.io_Device)
  167.     {
  168.         CloseDevice(ioa);
  169.     }
  170.     if(ioa->ioa_Request.io_Message.mn_ReplyPort)
  171.     {
  172.         DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
  173.     }
  174.     if(ioa)
  175.     {
  176.         FreeMem(ioa,sizeof(struct IOAudio));
  177.     }
  178. }
  179.  
  180. SetLength(LenPtr,buflen,DataHndl,ioa)
  181. ULONG *LenPtr,buflen;
  182. BYTE **DataHndl;
  183. struct IOAudio *ioa;
  184. {
  185.     if(buflen<= 131000)
  186.     {
  187.         (*LenPtr) = buflen;
  188.     }
  189.     else
  190.     {
  191.         (*LenPtr) = 131000;
  192.     }
  193.  
  194.     ioa->ioa_Length = (*LenPtr);
  195.     ioa->ioa_Data = (*DataHndl);
  196.  
  197.     if((*LenPtr) != buflen)
  198.     {
  199.         (*LenPtr) = buflen - 131000;
  200.         (*DataHndl) += 131000;
  201.     }
  202.     else
  203.     {
  204.         (*LenPtr) = 0;
  205.     }
  206. }    
  207.  
  208. FixLength(LenPtr,DataHndl,ioa)
  209. ULONG *LenPtr;
  210. BYTE **DataHndl;
  211. struct IOAudio *ioa;
  212. {
  213.     if((*LenPtr) > 131000)
  214.     {
  215.         ioa->ioa_Length = 131000;
  216.         ioa->ioa_Data = (*DataHndl);
  217.         (*LenPtr) -= 131000;
  218.         (*DataHndl) += 131000;
  219.     }
  220.     else
  221.     {
  222.         ioa->ioa_Length = (*LenPtr);
  223.         ioa->ioa_Data = (*DataHndl);
  224.         (*LenPtr) = 0;
  225.     }
  226. }
  227.